
(define (merge-weight xs ys weight?)
  (let ((next1 (stream-car xs))
	(next2 (stream-car ys)))
    (if (weight? next1 next2) ;next1 < next2
	(cons-stream next1 (merge-weight (stream-cdr xs) ys weight?))
	(cons-stream next2 (merge-weight xs (stream-cdr ys) weight?)))))

(define ones (cons-stream 1 ones))
(define integrates (cons-stream 1 (stream-map +
					      ones
					      integrates)))

(define (pairs S T merge-through)
  (cons-stream (list (stream-car S) (stream-car T))
	       (merge-through (stream-map (lambda (x) (list (stream-car S) x))
					  (stream-cdr T))
			      (pairs (stream-cdr S) (stream-cdr T) merge-through))))


(define answer-a
  (let ((a 0))
    (define (weight? a b)
      (define (get-sum alist)
	(+ (car alist) (cadr alist)))
      (< (get-sum a) (get-sum b)))
    (pairs integrates
	   integrates
	   (lambda (x y) (merge-weight x y weight?)))))

		

(define answer-b
  (let ((a 0))
    (define (weight? a b)
      (define (get-sum alist)
	(+ (* 2 (car alist)) (* 3 (cadr alist)) (* 5 (car alist) (cadr alist))))
      (< (get-sum a) (get-sum b)))
    (define (by235? x)
    (or (= (remainder x 2) 0) (= (remainder x 3) 0) (= (remainder x 5) 0)))
    (pairs (stream-filter by235? integrates)
	   (stream-filter by235? integrates)
	   (lambda (x y) (merge-weight x y weight?)))))
(define raj
  (let ((a 0))
    (define (weight? a b)
      (define (get-sum alist)
	(let ((i (car alist))
	      (j  (cadr alist)))
	  (+ (* i i i) (* j j j))))
      (< (get-sum a) (get-sum b)))
    (define (former-next=equal str)
      (let ((check-str (stream-cdr str)))
	(stream-filter (lambda (x) (let ((to-be-checked (stream-car check-str)))
				     (set! check-str (stream-cdr check-str))
				     (= x (to-be-checked))))
		       str)))
    (define (-former-next-equal str)
      (if (= (stream-car str) (stream-car (stream-cdr str)))
	  (cons-stream (stream-car str) (-former-next-equal (stream-cdr str)))
	  (-former-next-equal (stream-cdr str))))
    (define (to-num str)
      (define (get-sum alist)
	(let ((i (car alist))
	      (j (cadr alist)))
	  (+ (* i i i) (* j j j))))
      (cons-stream (get-sum (car-stream str)) (to-sum (stream-cdr str))))
    (-former-next-equal (to-sum (pairs integrates
				       integrates
				       (lambda (x y) (merge-weight x y weight?)))))))


(define answer-3.72
  (let ((a 0))
    (define (weight? a b)
      (define (get-sum alist)
	(let ((i (car alist))
	      (j  (cadr alist)))
	  (+ (* i i) (* j j))))
      (< (get-sum a) (get-sum b)))
    (define (former-next=equal str)
      (let ((check-str (stream-cdr str)))
	(stream-filter (lambda (x) (let ((to-be-checked (stream-car check-str)))
				     (set! check-str (stream-cdr check-str))
				     (= x (to-be-checked))))
		       str)))
    (define (-former-next-equal str)
      (if (and (= (stream-car str) (stream-car (stream-cdr str)))
	       (= (stream-car (stream-cdr str)) (stream-car (stream-cdr (stream-cdr str)))))
	  (cons-stream (stream-car str) (-former-next-equal (stream-cdr str)))
	  (-former-next-equal (stream-cdr str))))
    (define (to-num str)
      (define (get-sum alist)
	(let ((i (car alist))
	      (j (cadr alist)))
	  (+ (* i i) (* j j))))
      (cons-stream (get-sum (car-stream str)) (to-sum (stream-cdr str))))
    (-former-next-equal (to-sum (pairs integrates
				       integrates
				       (lambda (x y) (merge-weight x y weight?)))))))
    

(define (s-show s)
  (define (display-line a)
    (display a)
    (newline)
    a)
  (define (show-num num target)
    (if (> num target)
	0
	(begin
	  (display-line (stream-ref s num))
	  (show-num (+ num 1) target))))
  (show-num 0 10))
